import parse from '@bany/curl-to-json';
import { App, Button, Input } from 'antd';
import React from 'react';
import { useContextSelector } from 'use-context-selector';

import MyModal from '@/components/MyModal';
import { t } from '@/locales/i18n';
import { NodeInputKeyEnum } from '@/types/workflow/constant';
import { FlowNodeInputItemType } from '@/types/workflow/io';

import { WorkflowContext } from '../../../context';

const { TextArea } = Input;

type RequestMethod = 'get' | 'post' | 'put' | 'delete' | 'patch';
const methodMap: { [K in RequestMethod]: string } = {
  get: 'GET',
  post: 'POST',
  put: 'PUT',
  delete: 'DELETE',
  patch: 'PATCH',
};

const CurlImportModal = ({
  nodeId,
  inputs,
  onClose,
}: {
  nodeId: string;
  inputs: FlowNodeInputItemType[];
  onClose: () => void;
}) => {
  const { message } = App.useApp();
  const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
  const [curlContent, setCurlContent] = React.useState('');

  const handleFileProcessing = async (content: string) => {
    try {
      const requestUrl = inputs.find((item) => item.key === NodeInputKeyEnum.httpReqUrl);
      const requestMethod = inputs.find((item) => item.key === NodeInputKeyEnum.httpMethod);
      const params = inputs.find((item) => item.key === NodeInputKeyEnum.httpParams);
      const headers = inputs.find((item) => item.key === NodeInputKeyEnum.httpHeaders);
      const jsonBody = inputs.find((item) => item.key === NodeInputKeyEnum.httpJsonBody);

      if (!requestUrl || !requestMethod || !params || !headers || !jsonBody) return;

      if (content.trim() === '') {
        message.warning('cURL 内容不能为空');
        return;
      }

      const parsed = parse(content);

      if (!parsed.url) {
        throw new Error('url not found');
      }

      const newParams = Object.keys(parsed.params || {}).map((key) => ({
        key,
        value: parsed.params?.[key],
        type: 'string',
      }));
      const newHeaders = Object.keys(parsed.header || {}).map((key) => ({
        key,
        value: parsed.header?.[key],
        type: 'string',
      }));
      const newBody = JSON.stringify(parsed.data, null, 2);

      onChangeNode({
        nodeId,
        type: 'updateInput',
        key: NodeInputKeyEnum.httpReqUrl,
        value: {
          ...requestUrl,
          value: parsed.url,
        },
      });

      onChangeNode({
        nodeId,
        type: 'updateInput',
        key: NodeInputKeyEnum.httpMethod,
        value: {
          ...requestMethod,
          value: methodMap[parsed.method?.toLowerCase() as RequestMethod] || 'GET',
        },
      });

      onChangeNode({
        nodeId,
        type: 'updateInput',
        key: NodeInputKeyEnum.httpParams,
        value: {
          ...params,
          value: newParams,
        },
      });

      onChangeNode({
        nodeId,
        type: 'updateInput',
        key: NodeInputKeyEnum.httpHeaders,
        value: {
          ...headers,
          value: newHeaders,
        },
      });

      onChangeNode({
        nodeId,
        type: 'updateInput',
        key: NodeInputKeyEnum.httpJsonBody,
        value: {
          ...jsonBody,
          value: newBody,
        },
      });

      onClose();

      message.success(t('common.Import success'));
    } catch (error: any) {
      message.error(error.message);
      console.error(error);
    }
  };

  return (
    <MyModal
      isOpen
      onClose={onClose}
      iconSrc="ic-link"
      title={t('core.module.http.curl import')}
      w={600}
    >
      <div>
        <TextArea
          rows={20}
          value={curlContent}
          onChange={(e) => setCurlContent(e.target.value)}
          className="mt-2"
          placeholder={t('core.module.http.curl import placeholder')}
        />
      </div>
      <div className="ml-auto mt-4">
        <Button type="primary" onClick={() => handleFileProcessing(curlContent)}>
          {t('common.Confirm')}
        </Button>
      </div>
    </MyModal>
  );
};

export default React.memo(CurlImportModal);
